package com.dkts.oil.test.road;

import org.geotools.data.collection.ListFeatureCollection;
import org.geotools.feature.FeatureIterator;
import org.geotools.feature.simple.SimpleFeatureBuilder;
import org.geotools.feature.simple.SimpleFeatureTypeBuilder;
import org.geotools.geojson.feature.FeatureJSON;
import org.locationtech.jts.geom.*;
import org.locationtech.jts.linearref.LengthIndexedLine;
import org.opengis.feature.simple.SimpleFeature;
import org.opengis.feature.simple.SimpleFeatureType;

import java.io.FileReader;
import java.io.FileWriter;
import java.util.*;

public class RouteT1 {

    static class PortWithIndex {
        Point point;
        double index;
        Coordinate foot;
        String name;

        public PortWithIndex(Point point, double index, Coordinate foot, String name) {
            this.point = point;
            this.index = index;
            this.foot = foot;
            this.name = name;
        }
    }

    public static void main(String[] args) throws Exception {
        FeatureJSON fjson = new FeatureJSON();

        // 读取中心线
        FeatureIterator<SimpleFeature> lineIt = fjson.readFeatureCollection(new FileReader("src/main/resources/长江.geojson")).features();
        Geometry centerGeom = null;
        if (lineIt.hasNext()) {
            centerGeom = (Geometry) lineIt.next().getDefaultGeometry();
        }
        lineIt.close();

        GeometryFactory gf = new GeometryFactory();
        LineString centerLine;

        if (centerGeom instanceof MultiLineString) {
            List<Coordinate> coords = new ArrayList<>();
            MultiLineString mls = (MultiLineString) centerGeom;
            for (int i = 0; i < mls.getNumGeometries(); i++) {
                LineString ls = (LineString) mls.getGeometryN(i);
                Collections.addAll(coords, ls.getCoordinates());
            }
            centerLine = gf.createLineString(coords.toArray(new Coordinate[0]));
        } else {
            centerLine = (LineString) centerGeom;
        }

        LengthIndexedLine indexedLine = new LengthIndexedLine(centerLine);

        // 读取港口点并投影
        FeatureIterator<SimpleFeature> portIt = fjson.readFeatureCollection(new FileReader("src/main/resources/长江港口.geojson")).features();
        List<PortWithIndex> portsWithIndex = new ArrayList<>();
        while (portIt.hasNext()) {
            SimpleFeature feature = portIt.next();
            Point portPt = (Point) feature.getDefaultGeometry();
            String portName = (String) feature.getAttribute("name"); // 读取name字段
            double index = indexedLine.project(portPt.getCoordinate());
            Coordinate foot = indexedLine.extractPoint(index);
            portsWithIndex.add(new PortWithIndex(portPt, index, foot, portName));
        }
        portIt.close();

        // 排序港口按航线索引
        portsWithIndex.sort(Comparator.comparingDouble(p -> p.index));

        // ===== 分段路网：包含港口点连接 =====
        SimpleFeatureTypeBuilder segTypeBuilder = new SimpleFeatureTypeBuilder();
        segTypeBuilder.setName("ShippingRouteSegment");
        segTypeBuilder.add("geometry", LineString.class);
        segTypeBuilder.add("start_port", String.class);
        segTypeBuilder.add("end_port", String.class);
        SimpleFeatureType segType = segTypeBuilder.buildFeatureType();

        ListFeatureCollection segCollection = new ListFeatureCollection(segType);
        SimpleFeatureBuilder segFeatureBuilder = new SimpleFeatureBuilder(segType);

        for (int i = 0; i < portsWithIndex.size() - 1; i++) {
            PortWithIndex startPort = portsWithIndex.get(i);
            PortWithIndex endPort = portsWithIndex.get(i + 1);

            double startIdx = indexedLine.project(startPort.foot);
            double endIdx = indexedLine.project(endPort.foot);

            if (startIdx >= endIdx) continue;

            // 取 航线段
            LineString segLine = (LineString) indexedLine.extractLine(startIdx, endIdx);

            List<Coordinate> coords = new ArrayList<>();
            // 起点垂足
            coords.add(startPort.foot);
            // 到港口点
            coords.add(startPort.point.getCoordinate());
            // 回到垂足
            coords.add(startPort.foot);
            // 航线段
            coords.addAll(Arrays.asList(segLine.getCoordinates()));
            // 到后一个港口垂足
            coords.add(endPort.foot);
            // 到港口点
            coords.add(endPort.point.getCoordinate());
            // 回到垂足
            coords.add(endPort.foot);

            // 创建段 LineString
            LineString fullSegment = gf.createLineString(coords.toArray(new Coordinate[0]));

            segFeatureBuilder.add(fullSegment);
            segFeatureBuilder.add(startPort.name);
            segFeatureBuilder.add(endPort.name);
            segCollection.add(segFeatureBuilder.buildFeature(null));
        }

        // 写入分段路径 GeoJSON
        try (FileWriter writer = new FileWriter("src/main/resources/shipping_长江_segments_with_ports.geojson")) {
            fjson.writeFeatureCollection(segCollection, writer);
        }

        System.out.println("✔ 分段路径（含港口点连接） shipping_长江_segments_with_ports.geojson 生成完成");
    }
}
